#include "page.h"
#include "ui_page.h"
#include "widget.h"
//#include "progressbarthread.h"
#include "monitorthread.h"
//#include "mydialog.h"
#include <QDebug>
#include <cstring>

Page::Page(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Page)
{
    ui->setupUi(this);
    ui->rBtnA2B_backup->setChecked(true);
    ui->rBtnA2B->setChecked(true);

    connect(ui->srcTree, &QTreeWidget::itemExpanded, this, [=](QTreeWidgetItem *item){ //让子文件夹可以打开的
        if (item->childCount() == 0) { // 或者您可以使用自定义标记检查
            QString path = item->data(0, Qt::UserRole).toString(); // 假设我们以此方式存储了路径
            // 注意传递树控件指针，当前项作为父项，以及路径
            populateTreeWidgetWithDirs(item->treeWidget(), item, path);
        }
    });

    connect(ui->destTree, &QTreeWidget::itemExpanded, this, [=](QTreeWidgetItem *item) {
        if (item->childCount() == 0) { // 或者您可以使用自定义标记检查
            QString path = item->data(0, Qt::UserRole).toString(); // 假设我们以此方式存储了路径
            // 注意传递树控件指针，当前项作为父项，以及路径
            populateTreeWidgetWithDirs(item->treeWidget(), item, path);
        }
    });

    connect(ui->srcTree, &QTreeWidget::itemClicked, [=](QTreeWidgetItem *item, int column) { //将src文件树中的路径放到srcLine中
//        // 获取点击的文件树选项的目录路径
//        QString path = item->data(column, Qt::UserRole).toString();
        // 获取选中的目录的绝对路径
        QString relativePath = item->data(column, Qt::UserRole).toString();
        QString absolutePath = QDir::cleanPath(QDir::rootPath() + relativePath);
        // 将目录路径写入 QLineEdit
        ui->srcLine->setText(absolutePath);
    });

    connect(ui->destTree, &QTreeWidget::itemClicked, [=](QTreeWidgetItem *item, int column) { //将src文件树中的路径放到destLine中
//        // 获取点击的文件树选项的目录路径
//        QString path = item->data(column, Qt::UserRole).toString();
        // 获取选中的目录的绝对路径
        QString relativePath = item->data(column, Qt::UserRole).toString();
        QString absolutePath = QDir::cleanPath(QDir::rootPath() + relativePath);
        // 将目录路径写入 QLineEdit
        ui->destLine->setText(absolutePath);
    });
}

Page::~Page()
{
    delete ui;
}

void Page::populateTreeWidgetWithDirs(QTreeWidget *treeWidget, QTreeWidgetItem *parentItem, const QString &path) {

    // 设置为单选模式
    treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);

    QDir dir(path);
    dir.setFilter(QDir::NoDotAndDotDot | QDir::AllDirs); // 排除"."和".."，只列出目录
    QStringList dirs = dir.entryList();
    for (const QString &dirName : dirs) {
    QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);
    // 设置树状条目的图标
    QIcon folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirIcon);
    item->setIcon(0, folderIcon); // 假设这个条目代表一个目录
    item->setText(0, dirName); // 设置目录名
    item->setData(0, Qt::UserRole, path + "/" + dirName); // 存储完整路径以便稍后使用
    if(parentItem == nullptr) { // 如果是顶层目录，添加到treeWidget
            treeWidget->addTopLevelItem(item);
    }

    // 延迟加载子目录，只有在项目展开时才加载
    item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
    }
}

void Page::on_srcBtn_clicked()
{
    QString directoryPath = "/";
    QDir directory(directoryPath);

    populateTreeWidgetWithDirs(ui->srcTree,nullptr, directoryPath);
    ui->srcBtn->setEnabled(false);  // 设置按钮为不可点击状态

    return;
}

void Page::on_destBtn_clicked()
{
    QString directoryPath = "/";
    QDir directory(directoryPath);

    populateTreeWidgetWithDirs(ui->destTree,nullptr, directoryPath);
    ui->destBtn->setEnabled(false);  // 设置按钮为不可点击状态

    return;
}

int num = 0;
void Page::on_pBtnBackup_clicked()  //备份启动任务
{
    QString src = ui->srcLine->text();
    QByteArray byteArray = src.toUtf8();
    const char* charSrc = byteArray.constData();

    QString dest = ui->destLine->text();
    QByteArray byteArray_d = dest.toUtf8();
    const char* charDest = byteArray_d.constData();

    // 定义任务结构体
    BackupTask task;
    strcpy(task.source, charSrc);
    strcpy(task.destination, charDest);

//    qDebug() << task.source <<endl;
//    qDebug() << task.destination <<endl;
    // 进度条线程
    // 进度条线程的准备
    // 每个进程开始前先清空该变量
    dirSize = 0;
    written = 0;
    dirSize = calculateDirectorySize(task.source);
/***********************************************/


    // 创建线程和对话框对象
        //创建进度条对话框

    // 创建进度条窗口
//    QProgressDialog progressDialog("Progress", "Cancel", 0, 100, this);
//    progressDialog.setWindowTitle("Progress");
//    progressDialog.setWindowModality(Qt::WindowModal);
//    progressDialog.show();
//    progressDialog.setValue(0);

    // 创建监控线程
    MonitorThread thread;
    ui->progressBar->setValue(0);
    thread.setFraction(dirSize, ui->progressBar);
    // 连接信号和槽
//    connect(&thread,&MonitorThread::progressUpdated, ui->progressBar, [&](int value){
//        ui->progressBar->setValue(value);
//    });
//    ui->progressBar->setValue(20);
//    connect(&thread, &MonitorThread::progressUpdated, ui->progressBar, &QProgressBar::setValue);
//    QObject::connect(&thread, &MonitorThread::progressUpdated, ui->progressBar, [=](int val) {
//        qDebug() << "int page:" << val <<endl;
//    });

    // 启动线程
    thread.start();

//    // 模拟分子变化
//    num = 0;
//    while (true) {
//        // 在此处修改全局的分子变量的值
//        // 这里仅作示例，假设分子每隔一秒递增1
//        num++;
//        QThread::sleep(1);
//        if (num == 50) break;
//    }
//    // 等待线程完成
//    thread.wait();
/*****************************************/


    // 进度条线程启动
    pthread_t barThread;
    pthread_create(&barThread, NULL, draw_progress_bar_thread, NULL);

    //任务线程
    pthread_t taskThread;
    pthread_create(&taskThread, NULL, backup_directory_thread, (void*)&task);

    // 等待线程完成
    thread.wait();
    pthread_join(taskThread, NULL);
    pthread_join(barThread, NULL);
    QMessageBox::information(nullptr, "任务结束", "备份任务已完成！");


}

void Page::on_pBtnSync_clicked()  //同步启动任务
{
    QString src = ui->srcLine->text();
    QByteArray byteArray = src.toUtf8();
    const char* charSrc = byteArray.constData();

    QString dest = ui->destLine->text();
    QByteArray byteArray_d = dest.toUtf8();
    const char* charDest = byteArray_d.constData();

    // 定义任务结构体
    SyncJob task;
    strcpy(task.source, charSrc);
    strcpy(task.destination, charDest);

    qDebug() << task.source <<endl;
    qDebug() << task.destination <<endl;

    if (ui->rBtnB2A->isChecked()) {
        qDebug() << "Option 1 selected";
        task.mode = 1;
    } else if (ui->rBtnA2B->isChecked()) {
        qDebug() << "Option 2 selected";
        task.mode = 2;
    } else  if (ui->rBtnAB->isChecked()){
        qDebug() << "Option 3 selected";
        task.mode = 3;
    }
    dirSize = 0;
    written = 0;

    //先获得dirSize的值
    sync_directory(task.source, task.destination, task.mode); //只负责清扫两个目录
    if (task.mode == 1) { //根据对应mode进行拷贝 B2A
        dirSize = calculateDirectorySize(task.destination);
        printf("总共要【同步】的字节数：%lld\n", dirSize);
//        backup_diectory_sync(task.destination, task.source);
    } else if (task.mode == 2) { //A2B
        dirSize = calculateDirectorySize(task.source);
        printf("总共要【同步】的字节数：%lld\n", dirSize);
//        backup_diectory_sync(task.source, task.destination);
    } else if (task.mode == 3) { //AB
        long long olderDest = calculateDirectorySize(task.destination);
        dirSize = 2 * calculateDirectorySize(task.source) + calculateDirectorySize(task.destination);
        printf("总共要【同步】的字节数：%lld\n", dirSize);
//        backup_diectory_sync(task.source, task.destination);
//        backup_diectory_sync(task.destination, task.source);
    }

    //执行进度条类的实现
    MonitorThread thread;
    ui->progressBar->setValue(0);
    thread.setFraction(dirSize, ui->progressBar);
    thread.start();


    //任务线程
    pthread_t taskThread;
    pthread_create(&taskThread, NULL, sync_directory_thread, (void*)&task);

    pthread_join(taskThread, NULL);
    thread.wait();
    QMessageBox::information(nullptr, "任务结束", "同步任务已完成！");

}
